package cn.vendai.com.controller;

import cn.vendai.com.assistant.AIAgent;
import cn.vendai.com.entity.Message;
import cn.vendai.com.entity.UserRequest;
import cn.vendai.com.entity.dto.UserRequestDTO;
import cn.vendai.com.repository.MessageRepository;
import cn.vendai.com.utils.UserTransmittableThreadLocalContext;
import cn.vendcommon.com.annotation.RequestLogin;
import cn.vendcommon.com.entity.constants.CommonCodeMsg;
import cn.vendcommon.com.entity.Result;
import cn.vendai.com.service.ChatService;
import cn.vendcommon.com.entity.User;
import cn.vendcommon.com.entity.enums.CommonRedisKey;
import cn.vendcommon.com.exception.VendException;
import cn.vendcommon.com.utils.UserContext;
import com.alibaba.fastjson.JSON;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.*;
import reactor.core.publisher.Flux;

import java.time.Instant;
import java.util.concurrent.CompletableFuture;

@Slf4j
@RestController
@RequestMapping("/chat")
public class ChatController {


    @Autowired
    private ChatService chatService;
    @Autowired
    private AIAgent aiAgent;
    @Autowired
    private MessageRepository messageRepository;
    @Autowired
    private RedisTemplate redisTemplate;


    /**
     * 处理用户聊天请求(同步+无SSH流式输出)
     * @param userRequest
     * @return
     */
    @RequestLogin
    @PostMapping("/send")
    public Result<String> sendMessage(@RequestBody UserRequest userRequest) {
        try {
            int userId = Math.toIntExact(UserContext.getUserId());
            String response = chatService.chat(String.valueOf(userId),
                    userRequest.getConversationId(), userRequest.getContent());
            return Result.success(response);
        } catch (Exception e) {
            return Result.error("对话失败: " + e.getMessage());
        }
    }

    /**
     * 处理用户聊天请求(异步+SSH流式输出)
     * @param userRequest
     * @return
     */
    @RequestLogin
    @PostMapping(value = "/sendStream", produces = MediaType.TEXT_EVENT_STREAM_VALUE)
    public Flux<String> chat(@RequestBody UserRequestDTO userRequest) {
        String token = userRequest.getJwtToken();

        User user = JSON.parseObject(
                (String) redisTemplate.opsForValue().get(CommonRedisKey.USER_TOKEN.getRealKey(token)),
                User.class
        );
        if (user == null) {
            return Flux.error(new VendException(CommonCodeMsg.TOKEN_INVALID));
        }
        user.setWxOpenId(null);
        user.setLoginIP(null);
        user.setPassword(null);

        String conversationId = userRequest.getConversationId();

        // Flux.create 表示手动创建一个流式数据源，通过 emitter.next() 向前端推送消息。
        return Flux.create(emitter -> {
            // 1. 保存用户消息
            Message userMsg = new Message();
            userMsg.setUserId(String.valueOf(user.getId()));
            userMsg.setConversationId(conversationId);
            userMsg.setRole("user");
            userMsg.setContent(userRequest.getContent());
            userMsg.setCreatedAt(Instant.now());
            messageRepository.save(userMsg);

            // 使用StringBuilder累加AI消息并存储
            StringBuilder aiContentBuilder = new StringBuilder();

            // 2. 流式调用 AI
            aiAgent.chat(String.valueOf(user.getId()), userRequest.getContent() + "，我的账号Id为：" + user.getId())
                    .subscribe(
                            chunk -> {
                                emitter.next(chunk);  // 每次有片段结果就推送给前端
                                aiContentBuilder.append(chunk);
                            },
                            emitter::error,               // AI 异常也直接推给 SSE
                            () -> {
                                // 使用 CompletableFuture 异步保存完整 AI 消息
                                CompletableFuture.runAsync(() -> {
                                    Message aiMsg = new Message();
                                    aiMsg.setUserId(String.valueOf(user.getId()));
                                    aiMsg.setConversationId(conversationId);
                                    aiMsg.setRole("ai");
                                    aiMsg.setContent(aiContentBuilder.toString()); // 可以累加 Flux 输出
                                    aiMsg.setCreatedAt(Instant.now());
                                    messageRepository.save(aiMsg);
                                }).whenComplete((v, ex) -> {
                                    // 完成 SSE 推送
                                    emitter.complete();
                                    if (ex != null) {
                                        log.error("保存 AI 消息失败: {}", ex.getMessage());
                                    }
                                });
                            }
                    );
        });
    }




}
